#include <stddef.h>
#include "stdio.h"

typedef unsigned char   uint8_t;  //  8 bits
typedef unsigned int    uint16_t; // 16 bits
typedef unsigned long   uint32_t; // 32 bits



typedef enum {
	EC_DO,//缺省情况下，整型值从0开始
	EC_ENTER,
	EC_EXIT,
}step_t;
typedef void (*state_t)(step_t ec);//意思：state_t是一种函数指针的类型别名
/*************	功能说明	**************/

int count;


state_t pstate = NULL;//定义了一个函数指针？

void trans(state_t pnext);
/*************STATE-START**************/
void STATE_STANDBY_MODE(step_t ec);
void STATE_WORK_HOT_MODE_PRE(step_t ec);
void STATE_WORK_HOT_MODE(step_t ec);

void STATE_WORK_OUT_MODE(step_t ec);
void STATE_WORK_OUT_MODE_CHECK(step_t ec);

void STATE_PAUSE_MODE(step_t ec);

void STATE_CLEAR_MODE(step_t ec);
void STATE_CLEAR_MODE_CHECK(step_t ec);
/*************STATE-END**************/

static flag = 0;
void STATE_STANDBY_MODE(step_t ec)
{

	switch(ec) {
		case EC_DO:
            if(flag)
            {
                flag = 0;
                printf("trans befor ECDO\n");
               trans(STATE_WORK_HOT_MODE_PRE);
               printf("trans after ECDO\n");
            }
            else
            {
                printf("do noting1\n");
//                trans(STATE_WORK_HOT_MODE_PRE);
            }
            printf("do noting2\n");
			break;
		case EC_ENTER://进入STATE_STANDBY_MODE，会先进这里，下次才到DO里面循环
            printf("EC_ENTER\n");
			break;
        case EC_EXIT://退出STATE_STANDBY_MODE，如果指针没有指向NULL,会先进这里，然后进入下一个MODE的ENTER中
            printf("EC_EXIT\n");
			break;
		default:trans(STATE_STANDBY_MODE);
			break;
	}
}

void STATE_WORK_HOT_MODE_PRE(step_t ec)
{
	switch(ec) {
		case EC_DO:
			if(1)
            {
               trans(STATE_WORK_HOT_MODE);
            }
            else
            {
                trans(STATE_WORK_HOT_MODE);
            }


			break;
		case EC_ENTER:

			break;
        case EC_EXIT:

			break;
		default:trans(STATE_STANDBY_MODE);
			break;
	}
}

void STATE_WORK_HOT_MODE(step_t ec)
{
	switch(ec) {
		case EC_DO:
			if(1)
            {
               trans(STATE_WORK_OUT_MODE);
            }
            else
            {
                trans(STATE_WORK_OUT_MODE);
            }


			break;
		case EC_ENTER:

			break;
        case EC_EXIT:

			break;
		default:trans(STATE_STANDBY_MODE);
			break;
	}
}

void STATE_WORK_OUT_MODE(step_t ec)
{
	switch(ec) {
		case EC_DO:
			if(1)
            {
               trans(STATE_WORK_OUT_MODE_CHECK);
            }
            else
            {
                trans(STATE_WORK_OUT_MODE_CHECK);
            }


			break;
		case EC_ENTER:

			break;
        case EC_EXIT:

			break;
		default:trans(STATE_STANDBY_MODE);
			break;
	}
}

void STATE_WORK_OUT_MODE_CHECK(step_t ec)
{
	switch(ec) {
		case EC_DO:
			if(1)
            {
               trans(STATE_PAUSE_MODE);
            }
            else
            {
                trans(STATE_PAUSE_MODE);
            }

			break;
		case EC_ENTER:

			break;
        case EC_EXIT:

			break;
		default:trans(STATE_STANDBY_MODE);
			break;
	}
}

void STATE_PAUSE_MODE(step_t ec)
{
	switch(ec) {
		case EC_DO:
			if(1)
            {
               trans(STATE_CLEAR_MODE);
            }
            else
            {
                trans(STATE_CLEAR_MODE);
            }

			break;
		case EC_ENTER:

			break;
        case EC_EXIT:

			break;
		default:trans(STATE_STANDBY_MODE);
			break;
	}
}

void STATE_CLEAR_MODE(step_t ec)
{
	switch(ec) {
		case EC_DO:
			if(1)
            {
               trans(STATE_CLEAR_MODE_CHECK);
            }
            else
            {
                trans(STATE_CLEAR_MODE_CHECK);
            }

			break;
		case EC_ENTER:

			break;
        case EC_EXIT:

			break;
		default:trans(STATE_STANDBY_MODE);
			break;
	}
}

void STATE_CLEAR_MODE_CHECK(step_t ec)
{
	switch(ec) {
		case EC_DO:
			if(1)
            {
                printf("trans befor STATE_CLEAR_MODE_CHECK ECDO\n");
               trans(STATE_STANDBY_MODE);
            }
            else
            {
                trans(STATE_STANDBY_MODE);
            }

			break;
		case EC_ENTER:

			break;
        case EC_EXIT:

			break;
		default:trans(STATE_STANDBY_MODE);
			break;
	}
}
void trans(state_t pnext)
{
	if(pstate) {
		pstate(EC_EXIT);
	}
	pstate = pnext;
	pstate(EC_ENTER);
}


int fsm_fun(void) {
	trans(STATE_STANDBY_MODE);
	for(;count < 200; count++) {
		pstate(EC_DO);
	}
	return 0;
}

void fsm_init(void)
{
    flag = 1;
    trans(STATE_STANDBY_MODE);
}

void fsm_process(void)
{
    pstate(EC_DO);
}

void main(void)
{

    fsm_init();
	while (1)
	{
        fsm_process();
	}
}
